//============================================================================
// Name        : SelfServer.cpp
// Author      : zhengc
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include "Manager.h"
#include "Conf.h"
#include "common.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
using namespace std;

Manager *g_manager = NULL;

int prodaemon = 1;

static void parse_cmd(int argc, char **argv)
{
	int c;
	while ((c = getopt(argc, argv, "d:c:l:f")) != -1)
	{
		switch (c) {
		case 'd':
			if (optarg) {
				set_debuglevel(atoi(optarg));
			}
			break;
		case 'f':
			prodaemon = 0;
			break;
		case 'c':
			if (optarg) {
				SetConf(optarg);
			}
			break;
		case 'l':
			if (optarg) {
				set_logfile(optarg);
			}
			break;
		}
	}
}

void
sigchld_handler(int s)
{
	pid_t pid;
	int stat;

	while ((pid = waitpid(-1, &stat, WNOHANG)) > 0);
	return;
}

void termination_handler(int s)
{
	if (g_manager)
		g_manager->stop();
}

static void init_signal()
{
	struct sigaction sa;
	sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;
	if (sigaction(SIGCHLD, &sa, NULL) == -1) {
		debug(LOG_ERR, "sigaction(): %s", strerror(errno));
		exit(1);
	}

	sa.sa_handler = SIG_IGN;
	if (sigaction(SIGPIPE, &sa, NULL) == -1) {
		debug(LOG_ERR, "sigaction(): %s", strerror(errno));
		exit(1);
	}

	sa.sa_handler = termination_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = SA_RESTART;

	if (sigaction(SIGTERM, &sa, NULL) == -1) {
		debug(LOG_ERR, "sigaction(): %s", strerror(errno));
		exit(1);
	}

	if (sigaction(SIGQUIT, &sa, NULL) == -1) {
		debug(LOG_ERR, "sigaction(): %s", strerror(errno));
		exit(1);
	}

	if (sigaction(SIGINT, &sa, NULL) == -1) {
		debug(LOG_ERR, "sigaction(): %s", strerror(errno));
		exit(1);
	}
}

void main_func()
{
	g_manager = new Manager();
	if (!g_manager) {
		return;
	}
	if (g_manager->init()) {
		g_manager->start();
	}
	delete g_manager;
	g_manager = NULL;
}

int main(int argc, char **argv) {
	ConfInit();
	parse_cmd(argc, argv);
	ReadConf();
	init_signal();
	if (prodaemon)  {
		if (fork() == 0) {
			setsid();
			main_func();
		}
		exit(0);
	} else {
		main_func();
	}
	return 0;
}
